package sopraim.presenter.servlets;

import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.imgscalr.Scalr;
import org.json.JSONArray;
import org.json.JSONObject;
import sopraim.entity.TextMessage;
import sopraim.entity.User;
import sopraim.presenter.services.UserService;
import sopraim.presenter.services.util.Utils;

@WebServlet(name = "UploadServlet",urlPatterns = {
    "/sendFile",
    "/history"
})
public class UploadServlet extends HttpServlet {
    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     *
     */
    File uploadFolder = new File(System.getProperty("user.home"),"SopraIM/Uploads");
    
    public UploadServlet(){
        if(!uploadFolder.exists()){
            uploadFolder.mkdirs();
        }
    }
    public void downloadFile(HttpServletRequest request, HttpServletResponse response){
        File file = new File(uploadFolder, request.getParameter("getfile"));
        if (file.exists()) {
            int bytes = 0;
            ServletOutputStream op;
            try {
                op = response.getOutputStream();
                response.setContentType(getMimeType(file));
                response.setContentLength((int) file.length());
                response.setHeader( "Content-Disposition", "inline; filename=\"" + file.getName() + "\"" );
                
                byte[] bbuf = new byte[1024];
                DataInputStream in = new DataInputStream(new FileInputStream(file));
                
                while ((in != null) && ((bytes = in.read(bbuf)) != -1)) {
                    op.write(bbuf, 0, bytes);
                }
                
                in.close();
                op.flush();
                op.close();
            } catch (IOException ex) {
                Logger.getLogger(UploadServlet.class.getName()).log(Level.SEVERE, null, ex);
            }
            
        }
    }
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        String userPath = request.getServletPath();
        
        switch (userPath){
            case "/history":
                User localUser = (User)request.getSession().getAttribute("user");
                UserService userService = new UserService();
                Utils utils = new Utils();
                String type = request.getParameter("type");
                if(type!=null){
                    File path = new File(uploadFolder,localUser.getUsername()+"."+type);
                    switch(type){
                        case "txt" :
                            utils.toTextFile(localUser,path);
                            downloadFile(request, response);
                            break;
                    }
                }
                break;
            case "/sendFile":
                if (request.getParameter("getfile") != null && !request.getParameter("getfile").isEmpty()) {
                    downloadFile(request, response);
                } else if (request.getParameter("delfile") != null && !request.getParameter("delfile").isEmpty()) {
                    File file = new File(uploadFolder, request.getParameter("delfile"));
                    if (file.exists()) {
                        file.delete(); // TODO:check and report success
                    }
                } else if (request.getParameter("getthumb") != null && !request.getParameter("getthumb").isEmpty()) {
                    File file = new File(uploadFolder, request.getParameter("getthumb"));
                    if (file.exists()) {
                        System.out.println(file.getAbsolutePath());
                        String mimetype = getMimeType(file);
                        if (mimetype.endsWith("png") || mimetype.endsWith("jpeg")|| mimetype.endsWith("jpg") || mimetype.endsWith("gif")) {
                            BufferedImage im = ImageIO.read(file);
                            if (im != null) {
                                BufferedImage thumb = Scalr.resize(im, 75);
                                ByteArrayOutputStream os = new ByteArrayOutputStream();
                                if (mimetype.endsWith("png")) {
                                    ImageIO.write(thumb, "PNG" , os);
                                    response.setContentType("image/png");
                                } else if (mimetype.endsWith("jpeg")) {
                                    ImageIO.write(thumb, "jpg" , os);
                                    response.setContentType("image/jpeg");
                                } else if (mimetype.endsWith("jpg")) {
                                    ImageIO.write(thumb, "jpg" , os);
                                    response.setContentType("image/jpeg");
                                } else {
                                    ImageIO.write(thumb, "GIF" , os);
                                    response.setContentType("image/gif");
                                }
                                ServletOutputStream srvos = response.getOutputStream();
                                response.setContentLength(os.size());
                                response.setHeader( "Content-Disposition", "inline; filename=\"" + file.getName() + "\"" );
                                os.writeTo(srvos);
                                srvos.flush();
                                srvos.close();
                            }
                        }
                    } // TODO: check and report success
                } else {
                    PrintWriter writer = response.getWriter();
                    writer.write("call POST with multipart form data");
                }
        }
        
    }
    
    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     *
     */
    @SuppressWarnings("unchecked")
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        if (!ServletFileUpload.isMultipartContent(request)) {
            throw new IllegalArgumentException("Request is not multipart, please 'multipart/form-data' enctype for your form.");
        }
        
        ServletFileUpload uploadHandler = new ServletFileUpload(new DiskFileItemFactory());
        PrintWriter writer = response.getWriter();
        response.setContentType("application/json");
        JSONArray json = new JSONArray();
        try {
            List<FileItem> items = uploadHandler.parseRequest(request);
            for (FileItem item : items) {
                if (!item.isFormField()) {
                    File file = new File(uploadFolder, item.getName());
                    item.write(file);
                    JSONObject jsono = new JSONObject();
                    jsono.put("name", item.getName());
                    jsono.put("size", item.getSize());
                    jsono.put("url", "UploadServlet?getfile=" + item.getName());
                    jsono.put("thumbnail_url", "UploadServlet?getthumb=" + item.getName());
                    jsono.put("delete_url", "UploadServlet?delfile=" + item.getName());
                    jsono.put("delete_type", "GET");
                    json.put(jsono);
                    System.out.println(json.toString());
                }
            }
        } catch (FileUploadException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            writer.write(json.toString());
            writer.close();
        }
        
    }
    
    private String getMimeType(File file) {
        String mimetype = "";
        if (file.exists()) {
            if (getSuffix(file.getName()).equalsIgnoreCase("png")) {
                mimetype = "image/png";
            }else if(getSuffix(file.getName()).equalsIgnoreCase("jpg")){
                mimetype = "image/jpg";
            }else if(getSuffix(file.getName()).equalsIgnoreCase("jpeg")){
                mimetype = "image/jpeg";
            }else if(getSuffix(file.getName()).equalsIgnoreCase("gif")){
                mimetype = "image/gif";
            }else {
                javax.activation.MimetypesFileTypeMap mtMap = new javax.activation.MimetypesFileTypeMap();
                mimetype  = mtMap.getContentType(file);
            }
        }
        return mimetype;
    }
    
    
    
    private String getSuffix(String filename) {
        String suffix = "";
        int pos = filename.lastIndexOf('.');
        if (pos > 0 && pos < filename.length() - 1) {
            suffix = filename.substring(pos + 1);
        }
        return suffix;
    }
}